package services

import (
	"fmt"
	"github.com/inntu/backend/api/models"
	"github.com/inntu/backend/config"
	"gorm.io/gorm"
)

// CategoryService 分类服务（重构后统一命名）
type CategoryService struct {
	db *gorm.DB
}

// NewCategoryService 创建分类服务实例
func NewCategoryService() *CategoryService {
	return &CategoryService{db: config.GetGormDB()}
}

// GormCategoryService 保持向后兼容的别名
type GormCategoryService = CategoryService

// NewGormCategoryService 保持向后兼容的构造函数
func NewGormCategoryService(db *gorm.DB) *CategoryService {
	return &CategoryService{db: db}
}

// GetCategories 获取分类列表（移除page参数，改用关联表查询）
func (s *CategoryService) GetCategories(parentID *int, status *int) ([]models.Category, error) {
	var categories []models.Category
	query := s.db.Model(&models.Category{}).Preload("Items").Preload("Pages")

	if parentID != nil {
		query = query.Where("parent_id = ?", *parentID)
	}

	if status != nil {
		query = query.Where("status = ?", *status)
	}

	err := query.Order("id ASC").Find(&categories).Error
	return categories, err
}

// GetCategoriesByPage 根据页面获取分类列表（新方法）
func (s *CategoryService) GetCategoriesByPage(pageCode string, status *int) ([]models.Category, error) {
	var categories []models.Category

	// 首先获取分类ID列表
	var categoryIDs []int
	query := s.db.Table("categories").
		Joins("JOIN page_categories ON page_categories.category_id = categories.id").
		Joins("JOIN pages ON pages.id = page_categories.page_id").
		Where("pages.code = ?", pageCode)

	if status != nil {
		query = query.Where("categories.status = ?", *status)
	}

	err := query.Pluck("categories.id", &categoryIDs).Error
	if err != nil {
		return nil, err
	}

	// 然后使用Preload获取完整的分类和项目数据
	err = s.db.Preload("Items").Where("id IN ?", categoryIDs).Order("id ASC").Find(&categories).Error
	return categories, err
}

// GetCategory 获取分类详情
func (s *CategoryService) GetCategory(id int) (*models.Category, error) {
	var category models.Category
	err := s.db.First(&category, id).Error
	if err != nil {
		return nil, err
	}
	return &category, nil
}

// GetCategoryWithChildren 获取分类及其子分类
func (s *CategoryService) GetCategoryWithChildren(id int) (*models.Category, error) {
	var category models.Category
	err := s.db.Preload("Children").First(&category, id).Error
	if err != nil {
		return nil, err
	}
	return &category, nil
}

// CreateCategory 创建分类
func (s *CategoryService) CreateCategory(category *models.Category) error {
	return s.db.Create(category).Error
}

// CreateCategoryWithRelations 创建分类并建立关联关系（事务操作）
func (s *CategoryService) CreateCategoryWithRelations(req *models.CreateCategoryRequest) (*models.Category, error) {
	// 开始事务
	tx := s.db.Begin()
	if tx.Error != nil {
		return nil, tx.Error
	}

	// 回滚函数
	defer func() {
		if r := recover(); r != nil {
			tx.Rollback()
		}
	}()

	// 1. 创建分类
	category := req.ToCategory()
	if err := tx.Create(category).Error; err != nil {
		tx.Rollback()
		return nil, fmt.Errorf("创建分类失败: %v", err)
	}

	// 2. 建立页面关联关系
	for _, pageID := range req.PageIDs {
		// 检查页面是否存在
		var page models.Page
		if err := tx.Where("id = ? AND status = ?", pageID, 1).First(&page).Error; err != nil {
			tx.Rollback()
			return nil, fmt.Errorf("页面ID %d 不存在或已禁用", pageID)
		}

		// 检查关系是否已存在
		var count int64
		tx.Table("page_categories").Where("page_id = ? AND category_id = ?", pageID, category.ID).Count(&count)
		if count == 0 {
			if err := tx.Exec("INSERT INTO page_categories (page_id, category_id) VALUES (?, ?)", pageID, category.ID).Error; err != nil {
				tx.Rollback()
				return nil, fmt.Errorf("建立页面关联关系失败: %v", err)
			}
		}
	}

	// 3. 建立项目关联关系
	for _, itemID := range req.ItemIDs {
		// 检查项目是否存在
		var item models.Item
		if err := tx.Where("id = ? AND status = ?", itemID, 1).First(&item).Error; err != nil {
			tx.Rollback()
			return nil, fmt.Errorf("项目ID %d 不存在或已禁用", itemID)
		}

		// 检查关系是否已存在
		var count int64
		tx.Table("category_items").Where("category_id = ? AND item_id = ?", category.ID, itemID).Count(&count)
		if count == 0 {
			if err := tx.Exec("INSERT INTO category_items (category_id, item_id) VALUES (?, ?)", category.ID, itemID).Error; err != nil {
				tx.Rollback()
				return nil, fmt.Errorf("建立项目关联关系失败: %v", err)
			}
		}
	}

	// 提交事务
	if err := tx.Commit().Error; err != nil {
		return nil, fmt.Errorf("提交事务失败: %v", err)
	}

	return category, nil
}

// UpdateCategory 更新分类
// UpdateCategory 更新分类
func (s *CategoryService) UpdateCategory(category *models.Category) error {
	// 使用Omit排除created_at字段，避免更新创建时间
	return s.db.Omit("created_at").Save(category).Error
}

// DeleteCategory 删除分类（软删除）
func (s *CategoryService) DeleteCategory(id int) error {
	return s.db.Delete(&models.Category{}, id).Error
}

// GetCategoriesByParent 根据父分类ID获取子分类
func (s *CategoryService) GetCategoriesByParent(parentID *int) ([]models.Category, error) {
	return s.GetCategories(parentID, nil)
}

// SearchCategories 搜索分类
func (s *CategoryService) SearchCategories(keyword string) ([]models.Category, error) {
	var categories []models.Category
	err := s.db.Where("name LIKE ? OR description LIKE ?", "%"+keyword+"%", "%"+keyword+"%").
		Order("id ASC").Find(&categories).Error
	return categories, err
}

// GetCategoryWithItems 获取分类及其项目
func (s *CategoryService) GetCategoryWithItems(id int) (*models.Category, error) {
	var category models.Category
	err := s.db.Preload("Items").First(&category, id).Error
	if err != nil {
		return nil, err
	}
	return &category, nil
}

// AddItemToCategory 添加项目到分类
func (s *CategoryService) AddItemToCategory(categoryID, itemID int) error {
	// 检查分类和项目是否存在
	var category models.Category
	var item models.Item

	if err := s.db.Where("id = ? AND status = ?", categoryID, 1).First(&category).Error; err != nil {
		return err
	}

	if err := s.db.Where("id = ? AND status = ?", itemID, 1).First(&item).Error; err != nil {
		return err
	}

	// 检查关系是否已存在
	var count int64
	s.db.Table("category_items").Where("category_id = ? AND item_id = ?", categoryID, itemID).Count(&count)
	if count > 0 {
		return fmt.Errorf("该项目已经关联到此分类")
	}

	// 添加关联关系
	return s.db.Exec("INSERT INTO category_items (category_id, item_id) VALUES (?, ?)", categoryID, itemID).Error
}

// RemoveItemFromCategory 从分类移除项目
func (s *CategoryService) RemoveItemFromCategory(categoryID, itemID int) error {
	return s.db.Exec("DELETE FROM category_items WHERE category_id = ? AND item_id = ?", categoryID, itemID).Error
}
